import 'dart:io';

import 'package:bigegg/common/sp/xmm_shared_preferences_util.dart';
import 'package:bigegg/dialog/xmm_business_dialog.dart';
import 'package:bigegg/global/xmm_app_const.dart';
import 'package:bigegg/page/im/chat/widget/xmm_message_item.dart';
import 'package:bigegg/page/im/chat/xmm_chat_controller.dart';
import 'package:bigegg/utils/xmm_date_utils.dart';
import 'package:bigegg/utils/xmm_emoji.dart';
import 'package:bigegg/utils/xmm_media_utils.dart';
import 'package:bigegg/utils/xmm_string_utils.dart';
import 'package:bigegg/utils/xmm_toast_util.dart';
import 'package:bigegg/widget/image/xmm_circle_cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:svgaplayer_flutter/svgaplayer_flutter.dart';

import '../../../global/im/xmm_im_manager.dart';
import '../../../global/routes/xmm_routes.dart';
import '../../../global/user/xmm_account_manager.dart';
import '../../../res/xmm_img.dart';

class XmmChatPage extends StatefulWidget {
  const XmmChatPage({super.key});

  @override
  State<StatefulWidget> createState() {
    return XmmChatPageState();
  }
}

class XmmChatPageState extends State<XmmChatPage> {
  final XmmChatController controller = Get.find<XmmChatController>();

  final TextEditingController _contentController = TextEditingController();

  ScrollController? _scrollController;

  final userId = Get.arguments;

  final inputBarStatus = InputBarStatus.normal.obs;

  final FocusNode focusNode = FocusNode();

  final _keyboardHeight = 200.w;

  final double _maxUpDistance = 75.w;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    _scrollController?.addListener(() async {
      if (_scrollController?.position.pixels ==
          _scrollController?.position.maxScrollExtent) {
        //滚动到底部
        controller.loadMoreHistoryMessage(userId);
      }
    });
    focusNode.addListener(() {
      if (focusNode.hasFocus) {
        switchInputBar(InputBarStatus.normal);
      }
    });
    () async {
      await controller.getUserInfo(userId);
      await controller.loadHistoryMessage(userId);
    }();
  }

  @override
  void dispose() {
    _scrollController?.dispose();
    _contentController.dispose();
    //关闭页面清除未读数
    XmmImManager.instance.clearUnreadCount(userId);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Obx(
        () => Visibility(
          visible: controller.isInit.value,
          child: Stack(
            children: [
              Column(
                children: [
                  toolBarWidget(),
                  listWidget(),
                  bottomToolWidget(),
                  Obx(() => bottomToolsContentWidget()),
                  Container(
                    color: const Color(0xFFF6F7F8),
                    height: MediaQuery.of(context).padding.bottom,
                  )
                ],
              ),
              Obx(() => _extraCenterWidget())
            ],
          ),
        ),
      ),
    );
  }

  Widget toolBarWidget() {
    return Container(
      color: const Color(0xFF15E8C2),
      padding: EdgeInsets.only(top: context.mediaQueryPadding.top),
      height: context.mediaQueryPadding.top + 44.w,
      child: Stack(
        alignment: Alignment.center,
        children: [
          Row(
            children: [
              GestureDetector(
                child: Container(
                  margin: const EdgeInsets.only(left: 20),
                  width: 32.w,
                  height: 32.w,
                  padding: EdgeInsets.all(5.w),
                  decoration: const BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.white,
                  ),
                  child: Image.asset(XmmImg.backIcon),
                ),
                onTap: () => Get.back(),
              ),
              Visibility(
                visible: userId !=
                    XmmAccountManager.instance.strategy?.userServiceAccountId,
                child: SizedBox(width: 16.w),
              ),
              Visibility(
                visible: userId !=
                    XmmAccountManager.instance.strategy?.userServiceAccountId,
                child: XmmCircleCachedNetworkImage(
                  imageUrl: controller.userInfo?.getAvatarUrl ?? "",
                  width: 32.w,
                  height: 32.w,
                ),
              ),
              SizedBox(width: 8.w),
              Expanded(
                child: Text(
                  XmmStringUtils.truncateText(
                      controller.userInfo?.nickname ?? "", 16),
                  style: TextStyle(
                    fontSize: 18.sp,
                    color: const Color(0xFF202020),
                  ),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              Visibility(
                visible: userId !=
                    XmmAccountManager.instance.strategy?.userServiceAccountId,
                child: GestureDetector(
                  onTap: () => XmmBusinessDialog.showMoreDialog(userId),
                  child: Container(
                      margin: const EdgeInsets.only(right: 20),
                      width: 32.w,
                      height: 32.w,
                      padding: EdgeInsets.all(5.w),
                      decoration: const BoxDecoration(
                        shape: BoxShape.circle,
                        color: Colors.white,
                      ),
                      child: Image.asset(XmmImg.moreIcon)),
                ),
              )
            ],
          ),
          Positioned(
            top: 7.w,
            right: 74.w,
            child: Image.asset(
              "assets/images/xmm_icon_chat_image.png",
              width: 65.w,
              height: 54.w,
            ),
          ),
        ],
      ),
    );
  }

  Widget listWidget() {
    return Flexible(
      child: Column(
        children: [
          Flexible(
            child: Obx(
              () => ListView.separated(
                padding: EdgeInsets.only(top: 32.w, bottom: 32.w),
                shrinkWrap: true,
                reverse: true,
                separatorBuilder: (_, __) => const SizedBox(height: 32),
                itemCount: controller.messageList.length,
                itemBuilder: (context, index) {
                  var item = controller.messageList.elementAt(index);
                  return Column(
                    children: [
                      itemTitleWidget(index),
                      XmmMessageItem(item, controller.userInfo!),
                    ],
                  );
                },
              ),
            ),
          )
        ],
      ),
    );
  }

  Widget itemTitleWidget(int index) {
    bool needShow = false;
    if (index == controller.messageList.length - 1) {
      needShow = true;
    } else {
      var lastTime =
          controller.messageList.elementAt(index + 1).message.sentTime ?? 0;
      var curTime =
          controller.messageList.elementAt(index).message.sentTime ?? 0;
      if ((lastTime - curTime).abs() > 30000) {
        needShow = true;
      }
    }
    if (needShow) {
      var curTime =
          controller.messageList.elementAt(index).message.sentTime ?? 0;
      return Container(
        margin: const EdgeInsets.only(bottom: 10),
        child: Text(
          XmmDateUtils.convertTime(curTime),
          style: const TextStyle(
            fontSize: 11,
            color: Color(0x4D000000),
          ),
        ),
      );
    }
    return Container();
  }

  Widget bottomToolWidget() {
    return Container(
      // constraints: BoxConstraints(minHeight: 49.w),
      height: 49.w,
      color: const Color(0xFFF6F7F8),
      child: Row(
        children: [
          SizedBox(width: 16.w),
          Obx(() => voiceKeyboardSwitchWidget()),
          SizedBox(width: 10.w),
          Expanded(child: Obx(() => inputWidget())),
          GestureDetector(
            onTap: () => switchInputBar(InputBarStatus.emoji),
            child: Container(
              margin: EdgeInsets.only(left: 20.w),
              width: 32,
              height: 32,
              child: Image.asset("assets/images/xmm_icon_chat_emo.png"),
            ),
          ),
          GestureDetector(
            onTap: () => switchInputBar(InputBarStatus.extend),
            child: Container(
              margin: EdgeInsets.only(left: 20.w, right: 16.w),
              width: 32,
              height: 32,
              child: Image.asset("assets/images/xmm_icon_chat_add.png"),
            ),
          )
        ],
      ),
    );
  }

  Widget voiceKeyboardSwitchWidget() {
    return GestureDetector(
      onTap: () async {
        PermissionStatus status = await Permission.microphone.request();
        if (status != PermissionStatus.granted) {
          XmmToastUtils.show("You have not authorised this permission.");
          return;
        }
        switchInputBar(InputBarStatus.voice);
      },
      child: Image.asset(
        inputBarStatus.value == InputBarStatus.voice
            ? "assets/images/xmm_icon_chat_keyboard.png"
            : "assets/images/xmm_icon_chat_voice.png",
        width: 32,
        height: 32,
      ),
    );
  }

  Widget inputWidget() {
    if (inputBarStatus.value == InputBarStatus.voice) {
      return voiceInputWidget();
    } else {
      return textFieldInputWidget();
    }
  }

  Widget textFieldInputWidget() {
    return Container(
      padding: EdgeInsets.only(left: 12.w, right: 12),
      alignment: Alignment.center,
      height: 32,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(4),
      ),
      child: TextField(
        onTapOutside: (e) => focusNode.unfocus(),
        onSubmitted: (content) => _sendTextMessage(content),
        controller: _contentController,
        decoration: const InputDecoration(
          isCollapsed: true,
          contentPadding: EdgeInsets.zero,
          border: InputBorder.none,
          hintText: "Enter here......",
          hintStyle: TextStyle(
            fontSize: 12,
            color: Color(0x4D000000),
          ),
        ),
        focusNode: focusNode,
        autofocus: false,
        maxLines: 5,
        minLines: 1,
        keyboardType: TextInputType.text,
        textInputAction: TextInputAction.send,
        cursorColor: const Color(0xFF006BE1),
        style: const TextStyle(
          fontSize: 15,
          color: Color(0xFF31456A),
          fontWeight: FontWeight.w500,
          height: 1.4,
        ),
      ),
    );
  }

  Widget voiceInputWidget() {
    return GestureDetector(
      onPanUpdate: (details) => _onPanUpdate(details),
      onPanDown: (details) => _onPanDown(),
      onPanEnd: (details) => _onPanEnd(details),
      onPanCancel: () => _onPanCancel(),
      child: Container(
        padding: EdgeInsets.only(left: 12.w),
        alignment: Alignment.center,
        height: 32,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(4),
        ),
        child: const Text(
          "Hold to talk",
          style: TextStyle(
            fontSize: 12,
            color: Color(0xFF202020),
          ),
        ),
      ),
    );
  }

  Widget bottomToolsContentWidget() {
    if (inputBarStatus.value == InputBarStatus.extend) {
      return extendContentWidget();
    } else if (inputBarStatus.value == InputBarStatus.emoji) {
      return emojiContentList();
    } else {
      return Container();
    }
  }

  Widget emojiContentList() {
    var emojiList = XmmEmoji.emojiList;
    return Container(
      color: const Color(0xFFF6F7F8),
      height: _keyboardHeight,
      child: GridView(
        padding: EdgeInsets.zero,
        scrollDirection: Axis.vertical,
        gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
          maxCrossAxisExtent: MediaQuery.of(context).size.width / 8,
        ),
        children: List.generate(
          emojiList.length,
          (index) {
            return GestureDetector(
              onTap: () {
                _contentController.text =
                    _contentController.text + emojiList[index];
                _contentController.selection = TextSelection.fromPosition(
                    TextPosition(offset: _contentController.text.length));
              },
              child: Center(
                widthFactor: MediaQuery.of(context).size.width / 8,
                heightFactor: MediaQuery.of(context).size.width / 8,
                child: Text(
                  emojiList[index],
                  style: const TextStyle(fontSize: 25),
                ),
              ),
            );
          },
        ),
      ),
    );
  }

  Widget extendContentWidget() {
    return Container(
      height: _keyboardHeight,
      padding: EdgeInsets.all(20.w),
      color: const Color(0xFFF6F7F8),
      child: Row(
        children: [
          extendItemWidget(
            "assets/images/xmm_icon_chat_pic.png",
            "Pic",
            () async {
              String? path = await XmmMediaUtils.pickImage();
              if (path != null) {
                controller.sendImageMessage(path, userId);
              }
            },
          ),
          SizedBox(width: 20.w),
          extendItemWidget(
            "assets/images/xmm_icon_chat_file.png",
            "File",
            () async {
              File? file = await XmmMediaUtils.pickFile();
              if (file != null) {
                controller.sendFileMessage(file.path, userId);
              }
            },
          ),
        ],
      ),
    );
  }

  Widget extendItemWidget(String image, String text, Function() clicked) {
    return GestureDetector(
      onTap: () => clicked.call(),
      child: Column(
        children: [
          Image.asset(image, width: 42.w, height: 42.w),
          const SizedBox(height: 5),
          Text(text, style: TextStyle(fontSize: 13.sp))
        ],
      ),
    );
  }

  Widget _extraCenterWidget() {
    if (controller.isRecording.value) {
      return recordWidget();
    } else {
      return Container();
    }
  }

  Widget recordWidget() {
    var canSendAudio = controller.isCanSendAudio.value;
    Widget voiceWidget = SizedBox(
      height: 84.h,
      child: canSendAudio
          ? SizedBox(
              width: 131.w,
              child: const SVGASimpleImage(
                assetsName: 'assets/images/svga/xmm_record_voice_start.svga',
              ),
            )
          : Image.asset(
              'assets/images/xmm_icon_chat_record_voice_cancel.png',
              width: 131.w,
            ),
    );
    Widget textWidget = Text(
      canSendAudio ? "Release Send" : "Release Cancel",
      style: const TextStyle(
        fontSize: 16,
        color: Colors.white,
      ),
    );
    Widget bottomContainer = CustomPaint(
      painter: _WSArcPainter(),
      child: Container(
        alignment: Alignment.center,
        height: 158.h,
        child: Image.asset(
          !canSendAudio
              ? 'assets/images/xmm_icon_chat_record_cancel.png'
              : 'assets/images/xmm_icon_chat_record_start.png',
          width: 62.w,
          height: 62.h,
        ),
      ),
    );
    return Container(
      alignment: Alignment.bottomCenter,
      color: const Color(0x99000000),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          voiceWidget,
          SizedBox(height: 111.w),
          textWidget,
          SizedBox(height: 8.w),
          bottomContainer,
        ],
      ),
    );
  }

  void switchInputBar(InputBarStatus status) {
    if (inputBarStatus.value != status) {
      inputBarStatus.value = status;
    } else {
      inputBarStatus.value = InputBarStatus.normal;
    }
    if (status != InputBarStatus.normal &&
        status != InputBarStatus.emoji &&
        focusNode.hasFocus) {
      focusNode.unfocus();
    }
  }

  void _sendTextMessage(String content) {
    if (content.isEmpty) {
      return;
    }
    controller.sendTextMessage(content, userId);
    _contentController.text = "";
  }

  void _onPanUpdate(DragUpdateDetails details) {
    if (details.localPosition.dy < 0 &&
        details.localPosition.dy.abs() > _maxUpDistance) {
      controller.isCanSendAudio.value = false;
    } else {
      controller.isCanSendAudio.value = true;
    }
  }

  /// 按下，开始录音
  void _onPanDown() {
    controller.isCanSendAudio.value = true;
    controller.isRecording.value = true;
    controller.startRecord();
  }

  /// 松开，结束录音
  void _onPanEnd(DragEndDetails details) {
    if (controller.isCanSendAudio.value) {
      controller.stopRecord();
    } else {
      controller.cancelRecord();
    }
    controller.isRecording.value = false;
    controller.isCanSendAudio.value = false;
  }

  void _onPanCancel() {
    controller.cancelRecord();
    controller.isRecording.value = false;
    controller.isCanSendAudio.value = false;
  }
}

enum InputBarStatus {
  normal, //正常
  voice, //语音输入
  emoji, // emoji输入
  extend, //扩展栏
}

class _WSArcPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.white
      ..style = PaintingStyle.fill;

    final path = Path()
      ..moveTo(0, size.height) // Start at the bottom-left corner
      ..lineTo(0, size.height - 128.h) // Move up by 100 pixels
      ..quadraticBezierTo(size.width / 2, size.height - 158.h, size.width,
          size.height - 128.h) // Draw a quadratic bezier curve
      ..lineTo(
          size.width, size.height) // Draw a line to the bottom-right corner
      ..close(); // Close the path

    canvas.drawPath(path, paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}
